#pragma once

#include "IPayload.h"
#include "IEndPoint.h"

namespace RoomFW {

//
// Room Signals
//
enum RoomSignals
{
	Q_ROOM_SIG = Q_USER_SIG,
	Q_ERROR_TRAN
};


//
// Class:	RoomMessage
//
// Description:	The Room Message type
//
// Author:	Andrew Sage
//
class RoomMessage : public QEvent
{
public:

	//
	// Method:	RoomMessage
	//
	// Description:	Constructor
	//
	// Parameters:
	//
	//	portIndex - Destination port index.
	//
	//	messageID - Message ID.
	//
	//	payload - Message payload.
	//
	RoomMessage(
		PortIndex portIndex,
		MessageID messageID,
		IPayloadSP payload = IPayloadSP(),
		const char* senderName = "",
		IEndPointSP replyEndpoint = IEndPointSP(),
		int replyId = 0);

	//
	// Accessors
	//
	PortIndex	portIndex() const;
	MessageID	messageID() const;
	IPayloadSP	payload() const;
	const char* senderName() const;

	//
	// Method:	releasePayload
	//
	// Description:	Release ownership of payload.  Also returns it.
	//
	// Parameters:	None.
	//
	// Return:	Payload.
	//
	IPayloadSP releasePayload();

	//
	// Method:	reply
	//
	// Description:	Send a message in reply to this one.
	//
	//	messageID -	Message ID
	//
	//	payload	- Message Payload
	//
	// Return - Success.  Fails on reply to synchronous call if caller
	//	has timed out.  May also throw on other errors (e.g. reciever errored).
	bool reply(MessageID messageID, IPayloadSP payload = IPayloadSP()) const
		throw (SendMessageError);

	//
	// Needed for timer and relay port implementation.
	//
	friend class ActiveObject;
	IEndPointSP replyEndpoint() const;
	int replyId() const;

private:

	//
	// Destination port index.
	//
	PortIndex	portIndex_;

	//
	// Message ID.
	//
	MessageID	messageID_;

	//
	// Message payload.
	//
	IPayloadSP	payload_;

	//
	// Sender's name for logging.
	//
	std::string senderName_;

	//
	// Endpoint for replies.
	//
	IEndPointSP replyEndpoint_;

	//
	// Id for remote replies.
	//
	int replyId_;
};
typedef ::boost::shared_ptr<RoomMessage> RoomMessageSP;

}
